/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */
 
 
#include "fosfor_volume.h"
#include "support.h"

G_DEFINE_TYPE(FosforVolume, fosfor_volume, CLUTTER_TYPE_GROUP);
static GObjectClass *parent_class = NULL;

static void fosfor_volume_dispose(GObject * object);
static void fosfor_volume_paint(ClutterActor *actor);
static void fosfor_volume_allocate(ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags);

static gboolean on_rect_enter(ClutterActor * actor, ClutterEvent * event, gpointer data)
{
	FosforVolume *volume = FOSFOR_VOLUME(actor);
	ClutterColor *black;

	black = clutter_color_new(0, 0, 0, 255);	
	
	clutter_actor_animate(volume->background, CLUTTER_LINEAR, 100, "opacity", 0xaa, NULL);

	return TRUE;
}

static gboolean on_rect_leave(ClutterActor * actor, ClutterEvent * event, gpointer data)
{
	FosforVolume *volume = FOSFOR_VOLUME(actor);
	ClutterColor *white;

	white = clutter_color_new(255,255,255,255);
	
	clutter_actor_animate(volume->background, CLUTTER_LINEAR, 100, "opacity", 0x00, NULL);
	    
	return TRUE;
}

static gboolean on_button_press(ClutterActor * actor, ClutterButtonEvent * event, gpointer data)
{
	FosforVolume *volume = FOSFOR_VOLUME(data);
	if (event->button == 1) {
		volume->mouse_down = TRUE;
	}
	return TRUE;
}

static gboolean on_button_release(ClutterActor * actor, ClutterButtonEvent * event, gpointer data)
{
	gfloat value;
	gfloat actor_x, actor_y;
	
	FosforVolume *volume = FOSFOR_VOLUME(data);
	if (event->button == 1 && volume->mouse_down) {
		clutter_actor_transform_stage_point(actor, event->x, event->y, &actor_x, &actor_y);
		value = (actor_x / (clutter_actor_get_width(volume->level) - 8.0));	
		//printf("actor_x = %f, width = %f, value = %f\n",actor_x,clutter_actor_get_width(volume->level), value);
		volume->mouse_down = FALSE;
		fosfor_volume_set_value(volume, value);
		g_signal_emit_by_name(volume, "percentage-changed", volume->percentage);
		
	} 

	return TRUE;
}

static gboolean on_scroll_event(ClutterActor * actor, ClutterScrollEvent * event, gpointer data)
{
	FosforVolume *volume = FOSFOR_VOLUME(data);
	
	if (event->direction == CLUTTER_SCROLL_UP)
		fosfor_volume_set_value(volume, volume->percentage + 0.1);
	if (event->direction == CLUTTER_SCROLL_DOWN)
		fosfor_volume_set_value(volume, volume->percentage - 0.1);
	g_signal_emit_by_name(volume, "percentage-changed", volume->percentage);

	return FALSE;
}

static void fosfor_volume_class_init(FosforVolumeClass * class)
{
	parent_class = g_type_class_peek_parent(class);
	G_OBJECT_CLASS(class)->dispose = fosfor_volume_dispose;
	CLUTTER_ACTOR_CLASS(class)->paint = fosfor_volume_paint;
	CLUTTER_ACTOR_CLASS(class)->allocate = fosfor_volume_allocate;

	g_signal_new("percentage-changed", FOSFOR_TYPE_VOLUME, 
    								G_SIGNAL_RUN_LAST, 
    								G_STRUCT_OFFSET (FosforVolumeClass, percentage_changed), 
    								NULL, NULL,
    								g_cclosure_marshal_VOID__DOUBLE,G_TYPE_NONE,1,G_TYPE_DOUBLE);	

}

static void fosfor_volume_init(FosforVolume * volume)
{

	clutter_actor_set_reactive(CLUTTER_ACTOR(volume), TRUE);
	g_signal_connect(CLUTTER_ACTOR(volume), "enter-event", G_CALLBACK(on_rect_enter), NULL);
    g_signal_connect(CLUTTER_ACTOR(volume), "leave-event", G_CALLBACK(on_rect_leave), NULL);

}

static void fosfor_volume_dispose(GObject * object)
{
	G_OBJECT_CLASS(parent_class)->dispose(object);
}

static void fosfor_volume_paint(ClutterActor *actor)
{
	FosforVolume *volume = FOSFOR_VOLUME(actor);
	cairo_t *cr;
	gfloat x,y, width, height,offset;

	if (volume->width == 0 || volume->height == 0)
		return;

	// draw the highlight
	clutter_cairo_texture_set_surface_size(CLUTTER_CAIRO_TEXTURE(volume->background), volume->width, volume->height);
	clutter_cairo_texture_clear(CLUTTER_CAIRO_TEXTURE(volume->background));

	cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(volume->background));

  	/* draw on the context */
	//cairo_set_source_rgb(cr, 1.0,1.0,1.0);
	cairo_set_source_rgb(cr, window->style->base[1].red / 65535.0, window->style->base[1].green / 65535.0, window->style->base[1].blue / 65535.0);	
	cairo_set_line_width(cr, 2.0);
	cairo_rounded_rectangle(cr, 0.0,0.0, volume->width ,volume->height, 10.0);

	cairo_fill_preserve(cr);

	cairo_stroke(cr);	
	cairo_destroy (cr);

	clutter_cairo_texture_set_surface_size(CLUTTER_CAIRO_TEXTURE(volume->level), volume->width - clutter_actor_get_width(volume->icon), volume->height);
	clutter_cairo_texture_clear(CLUTTER_CAIRO_TEXTURE(volume->level));
	//printf("level = %f x %f\n",clutter_actor_get_width(volume->level),clutter_actor_get_height(volume->level));
	// position the thumb
	clutter_actor_set_position(volume->thumb,clutter_actor_get_width(volume->icon) + 2.0 + (volume->percentage * (clutter_actor_get_width(volume->level) - 8.0)), clutter_actor_get_width(volume->level) / 4.0); 

	// paint the triangle

	offset = clutter_actor_get_height(volume->icon) * 0.3;
	x = 2.0;
	y = (clutter_actor_get_height(volume->icon) * 0.4) + offset;
	width = clutter_actor_get_width(volume->level) - 8.0;
	height = offset;

	cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(volume->level));

	cairo_new_path(cr);
	cairo_set_source_rgb(cr, window->style->bg[0].red / 65535.0, window->style->bg[0].green / 65535.0, window->style->bg[0].blue / 65535.0);	
	cairo_set_line_width(cr, 2.0);
	cairo_move_to(cr,x,y);
	cairo_line_to(cr,x + width,y);
	cairo_line_to(cr,x + width,height);
	cairo_close_path(cr);
	cairo_fill_preserve(cr);
	cairo_stroke(cr);	

	width = (clutter_actor_get_width(volume->level) - 8.0) * volume->percentage;
	height = ((clutter_actor_get_height(volume->icon) - (clutter_actor_get_height(volume->icon) * volume->percentage)) * 0.4) + offset;
	
	cairo_new_path(cr);
	cairo_set_source_rgb(cr, window->style->light[3].red / 65535.0, window->style->light[3].green / 65535.0, window->style->light[3].blue / 65535.0);	
	cairo_set_line_width(cr, 2.0);
	cairo_move_to(cr,x,y);
	cairo_line_to(cr,x + width,y);
	cairo_line_to(cr,x + width,height);
	cairo_close_path(cr);
	cairo_fill_preserve(cr);
	cairo_stroke(cr);	

	cairo_destroy (cr);
	
	CLUTTER_ACTOR_CLASS (parent_class)->paint(actor);
}

static void fosfor_volume_allocate(ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags)
{
	FosforVolume *volume = FOSFOR_VOLUME(actor);
	volume->width = box->x2-box->x1;
	volume->height = box->y2-box->y1;
	
	CLUTTER_ACTOR_CLASS (parent_class)->allocate(actor,box,flags);	
	
}

ClutterActor *fosfor_volume_new(GtkIconSize size)
{
	FosforVolume *volume;
	cairo_t *cr;
	
	volume = g_object_new (FOSFOR_TYPE_VOLUME, NULL);

	volume->size = size;

	volume->layout = clutter_box_layout_new();
	volume->container = clutter_box_new(volume->layout);
	clutter_box_layout_set_pack_start(CLUTTER_BOX_LAYOUT(volume->layout), FALSE);

	volume->background = clutter_cairo_texture_new(10,10);
	clutter_actor_set_opacity(volume->background, 0x00);			
	clutter_container_add_actor(CLUTTER_CONTAINER(volume),volume->background);

	// audio-volume-high, audio-volume-low, audio-volume-medium, audio-volume-muted
	volume->icon = fosfor_button_new_from_icon_name("audio-volume-muted",volume->size);
	fosfor_button_set_backlight(FOSFOR_BUTTON(volume->icon), FALSE);
	clutter_box_layout_pack(CLUTTER_BOX_LAYOUT(volume->layout),volume->icon,FALSE,FALSE,FALSE,CLUTTER_BOX_ALIGNMENT_START,CLUTTER_BOX_ALIGNMENT_CENTER);
	g_signal_connect(CLUTTER_ACTOR(volume->icon), "scroll-event", G_CALLBACK(on_scroll_event), volume);
	
	volume->level = clutter_cairo_texture_new(10,10);
	clutter_actor_set_reactive(volume->level, TRUE);
	clutter_actor_set_opacity(volume->level, 0xff);			
	clutter_box_layout_pack(CLUTTER_BOX_LAYOUT(volume->layout),volume->level,TRUE,TRUE,FALSE,CLUTTER_BOX_ALIGNMENT_START,CLUTTER_BOX_ALIGNMENT_CENTER);
	clutter_actor_set_position(volume->level,clutter_actor_get_width(volume->icon),0.0);
	g_signal_connect(CLUTTER_ACTOR(volume->level), "button-press-event", G_CALLBACK(on_button_press), volume);
    g_signal_connect(CLUTTER_ACTOR(volume->level), "button-release-event", G_CALLBACK(on_button_release), volume);
	g_signal_connect(CLUTTER_ACTOR(volume->level), "scroll-event", G_CALLBACK(on_scroll_event), volume);

	volume->thumb = clutter_cairo_texture_new(10,20);
	clutter_actor_set_anchor_point(volume->thumb,5.0,0.0);
	cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(volume->thumb));

  	/* draw on the context */
	clutter_cairo_texture_clear(CLUTTER_CAIRO_TEXTURE(volume->thumb));

	cairo_set_source_rgb(cr, window->style->fg[3].red / 65535.0, window->style->fg[3].green / 65535.0, window->style->fg[3].blue / 65535.0);	
	cairo_set_line_width(cr, 1.0);
	cairo_rounded_rectangle(cr, 1.0,1.0, 6.0, 12.0, 3.0);
	cairo_fill_preserve(cr);
	cairo_stroke(cr);
	cairo_destroy(cr);

    clutter_container_add_actor(CLUTTER_CONTAINER(volume),CLUTTER_ACTOR(volume->container));
    clutter_container_add_actor(CLUTTER_CONTAINER(volume),CLUTTER_ACTOR(volume->thumb));
	
	volume->width = clutter_actor_get_width(volume->icon) + clutter_actor_get_width(volume->icon) * 1.5;
	volume->height = clutter_actor_get_height(volume->icon) * 2.0;
	clutter_actor_set_size(CLUTTER_ACTOR(volume), volume->width, volume->height);

	fosfor_volume_set_value(volume, 1.0);


	return CLUTTER_ACTOR(volume);
}

void fosfor_volume_set_value(FosforVolume *volume, gdouble value)
{
	//printf("new value = %f\n",value);
	if (value < 0.0)
		value = 0.0;
	if (value > 0.99)
		value = 1.0;
	
	volume->percentage = value;
	if (value <= 0.0)
		fosfor_button_set_from_icon_name(FOSFOR_BUTTON(volume->icon),"audio-volume-muted",volume->size);
	if (value > 0.0 && value <= 0.5)
		fosfor_button_set_from_icon_name(FOSFOR_BUTTON(volume->icon),"audio-volume-low",volume->size);
	if (value > 0.5 && value < 0.99)
		fosfor_button_set_from_icon_name(FOSFOR_BUTTON(volume->icon),"audio-volume-medium",volume->size);
	if (value >= 0.99)
		fosfor_button_set_from_icon_name(FOSFOR_BUTTON(volume->icon),"audio-volume-high",volume->size);
		
	//gtk_clutter_texture_set_from_icon_name(CLUTTER_TEXTURE(volume->icon),clutter,"",volume->size,NULL);
}
